陣列就像容器一樣,放在裡面的東西稱為元素,會按照順序排好,每個元素都有其位置,稱為索引,找到索引值,就可以得知該位置元素的值。
建立陣列最直接的方式是使用中括號:
let ary1 = []; //建立一個空陣列,裡面沒有任何元素
let ary2 = [1,2,3]; //有3個元素的陣列,元素型別為number
let ary3 = [1,'a',true]; //不同型別的元素
let ary4 = [ [1,2,3],[4,5,6] ]; //陣列中也可以包含陣列
let ary5 = [ {x:1,y:2},{x:3,y:4} ]; //陣列中也可以包含物件
存取陣列中指定位置的值,必須使用索引值才能找到位置,並存取。
陣列的索引值是number型別,起始值是0。
let a = []; //空陣列
a[0] = 1; //設定a陣列的索引值0,也就是第1個元素值為1
a[1] = 2; //設定a陣列的索引值1,也就是第2個元素值為2
假設我們要存取o物件中的x屬性,會使用o.x或o['x'],同樣地,a[0]中,首先會將索引0轉為字串'0',表示a陣列(物件)的'0'屬性的值為1。
陣列的屬性名稱同時也是物件的屬性名稱,但只有在陣列的屬性名稱是介於0~ -1(含)之間的整數時,此時屬性才會被視為索引,同時也會影響該陣列另一個屬性length的值。
當我們要存取物件不存在的屬性時,不會發生錯誤,而是會回傳undefined。
陣列也是如此,不存在的索引或屬性名稱也是會得到undefined。
我們可以使用Array.isArray( )函式來判斷,該物件是否為陣列。
let ary = [1, 2, 3, 4, 5, 6];
let obj = {
x: 2,
y: 6
};
console.log(Array.isArray(ary)); //true
console.log(Array.isArray(obj)); //false
字串在JS中的行為類似陣列,每個元素都可視為字元,所以能用[ ]中括號,讀取值。
let str = 'Hello';
console.log(str[1]); //e
即便它的行為很像陣列,但實際型別依舊是string,而不是陣列。
let str = 'Hello';
console.log(str[1]); //e
console.log(typeof str); //string
console.log(Array.isArray(str)); //false
搜尋陣列中是否有符合給定值的元素,若有,就回傳第一個符合元素的索引值;若無,回傳-1。
searchElement:
指定要搜尋的值。
fromIndex:
指定起始索引值,若無給值,預設從第一個元素開始搜尋。
let ary = ['A', 'B', 'C', 'D', 'E', 'F'];
console.log(ary.indexOf('D')); //3
console.log(ary.indexOf('X')); //-1
console.log(ary.indexOf('D', 2)); //3
console.log(ary.indexOf('B', 2)); //-1
join( )方法可以將陣列中的所有元素轉成字串,並串接成一個字串,再回傳結果,若沒指定分隔符號,預設是逗號。
let ary = ['A', 'B', 'C', 'D'];
console.log(ary.join()); //A,B,C,D
console.log(ary.join('')); //ABCD
console.log(ary.join('-')); //A-B-C-D
將陣列中元素的排列順序倒轉過來,會改變原陣列。
let ary = ['A', 'B', 'C', 'D'];
console.log(ary.reverse()); //["D", "C", "B", "A"]
console.log(ary); //["D", "C", "B", "A"]
排序陣列中的元素,會先將元素轉字串,再依據字串的Unicode編碼進行排序,會改變原陣列。
let ary = ['Sun', 'Mon', 'Tue', 'Wed'];
console.log(ary.sort()); //["Mon", "Sun", "Tue", "Wed"]
console.log(ary); //["Mon", "Sun", "Tue", "Wed"]
但如果我們想要以數值的大小作排序,因為它比較的是字串,所以產生的結果不是預期的。
let nums = [10, 9, 50, 35];
console.log(nums.sort()); //[10, 35, 50, 9]
這時可以使用一個比較的函式做為引數,來判斷元素的大小與排列順序。
採用匿名函式,包括2個參數。如果a-b<0,那a會排在b的前面,如果a-b>0,那a會排在b的後面,如果a-b=0,排序不變。
let nums = [10, 9, 50, 35];
console.log(nums.sort(function (a, b) {
return a - b;
})); //[10, 35, 50, 9]
sort( )預設是將大寫排在前面。
let ary = ['Sun', 'mon', 'tue', 'Wed'];
console.log(ary.sort()); //["Sun", "Wed", "mon", "tue"]
如果想不區分大小寫排序,可藉由toLowerCase( )方法來達成。
將2個以上的陣列或進行陣列與字串合併成新的陣列。
合併2個:
let ary1 = ['a', 'b', 'c'];
let ary2 = ['d', 'e', 'f'];
console.log(ary1.concat(ary2)); //["a", "b", "c", "d", "e", "f"]
合併3個:
let ary1 = ['a', 'b', 'c'];
let ary2 = ['d', 'e', 'f'];
let ary3 = ['g', 'h', 'i'];
console.log(ary1.concat(ary2, ary3)); //["a", "b", "c", "d", "e", "f", "g", "h", "i"]
合併字面值與陣列:
let ary1 = ['a', 'b', 'c'];
let ary2 = ['d', 'e', 'f'];
let ary3 = ['g', 'h', 'i'];
console.log(ary1.concat(ary2, ary3, 'j', 'k', 1, 2));
//["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", 1, 2]
提取指定範圍的元素,回傳一個新陣列。
start:
起始索引值,如果為0,表示從第一個元素開始,-1表示從倒數第一個元素開始。
end:
結束索引值,擷取至該索引值之前的元素,3表示擷取至索引2為止,-3表示擷取至索引-4為止,如為空白,表示從start擷取至該陣列最後一個元素為止。
let ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.slice(1)); //["b", "c", "d", "e", "f"]
console.log(ary.slice(2, 5)); //["c", "d", "e"]
console.log(ary.slice(2, -1)); //["c", "d", "e"]
console.log(ary.slice(-3)); //["d", "e", "f"]
console.log(ary.slice(-4, 4)); //["c", "d"]
console.log(ary.slice(-5, -2)); //["b", "c", "d"]
從索引start開始,刪除deleteCount個元素並插入value,會改變原陣列。
start:
起始索引值,如果為0,表示從第一個元素開始,-1表示從倒數第一個元素開始。
deleteCount:
欲刪除元素的數量,若空白,則會刪除到最後一個元素為止;若為0或負數,則不會刪除任何元素。
value:
欲加入陣列的值,若空白,則不會加入任何元素。
回傳值:
被刪除的元素陣列。
let ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.splice(4)); // ["e", "f"]
console.log(ary); //["a", "b", "c", "d"]
ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.splice(3, 2)); //["d", "e"]
console.log(ary); // ["a", "b", "c", "f"]
ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.splice(3, 0)); //[]
console.log(ary); //["a", "b", "c", "d", "e", "f"]
ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.splice(-4, 2)); //["c", "d"]
console.log(ary); //["a", "b", "e", "f"]
ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.splice(-4, -2)); //[]
console.log(ary); //["a", "b", "c", "d", "e", "f"]
ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.splice(3, 0, 'A')); //[]
console.log(ary); //["a", "b", "c", "A", "d", "e", "f"]
ary = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(ary.splice(3, 1, 'A')); //["d"]
console.log(ary); //["a", "b", "c", "A", "e", "f"]
新增元素至陣列的開頭,並回傳陣列的新長度。
let a = [];
console.log(a.unshift('a')); //1
console.log(a.unshift('b')); //2
console.log(a.unshift('c', 'd')); //4
console.log(a); //["c", "d", "b", "a"]
需要注意,如果一次新增2個(以上)的元素,它會一次把所有元素插入,並維持原本在引數中的順序。
陣列也是物件,所以它也有toString()方法。
let ary = ['a', 'b', 'c'];
console.log(ary.toString()); //a,b,c
它會將元素轉成字串,並以逗號區隔成字串回傳。
會逐次地將元素傳入callbackfn,每傳遞一次,callbackfn就執行一次。
會改變原陣列。
value
元素值
index
索引值
array
傳入的陣列本身
let ary = [1, 2, 3, 4, 5, 6];
let sum = 0;
ary.forEach(function (v) {
sum += v;
})
console.log(sum); //21
ary.forEach(function (v, i, a) {
a[i] = v + 1;
})
console.log(ary); //[2, 3, 4, 5, 6, 7]
如果只傳入單一引數,就代表元素的值。
會逐次地將元素傳入callbackfn,每傳遞一次,callbackfn就執行一次。
回傳一個由callbackfn運算後,所組成的陣列。
let ary = [1, 2, 3, 4, 5, 6];
console.log(ary.map(function (x) {
return x * x;
})); //[1, 4, 9, 16, 25, 36]
map( )對callbackfn的呼叫方式跟forEach一樣,差別在於map( )會回傳新陣列,不會修改原陣列。
將元素依序傳入callbackfn中運算,運算結果為boolean值,回傳運算結果為true的元素所組成的陣列。
let ary = [1, 2, 3, 4, 5, 6];
console.log(ary.filter(function (x) {
return x < 4;
})); // [1, 2, 3]
實作搜尋篩選
let weeks = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
function filterWeeks(query) {
return weeks.filter(function (el) {
return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
})
}
console.log(filterWeeks('ur')); //["thursday", "saturday"]
console.log(filterWeeks('nd')); //["sunday", "monday"]
將el的值轉成小寫,再使用String的indexOf方法確認是否有包括query的值,若有回傳索引值會大於-1,比較結果為true,filter( )會將該元素放入回傳的陣列中;若無,indexOf( )回傳-1,比較結果為false,filter( )就不會取出該元素。
callbackfn會對陣列中的每個元素條件運算,只有全部的元素都為true,every( )才會回傳true,不然則回傳false。
let ary = [1, 2, 3, 4, 5, 6];
console.log(ary.every(function (x) {
return x < 4;
})); //fasle
console.log(ary.every(function (x) {
return x > 0;
})); //true
every( )會在第一次遇到運算結果為false時,就停止繼續對元素運算:
let ary = [1, 2, 3, 4, 5, 6];
console.log(ary.every(function (x) {
console.log(x);
return x < 4;
}));
callbackfn會對陣列中的每個元素條件運算,只要有一個(以上)元素為true,some( )就會回傳true,不然則回傳false。
let ary = [1, 2, 3, 4, 5, 6];
console.log(ary.some(function (x) {
return x < 4;
})); //true
some( )會在第一次遇到運算結果為true時,就停止繼續對元素運算:
let ary = [1, 2, 3, 4, 5, 6];
console.log(ary.some(function (x) {
console.log(x);
return x < 4;
}));
會逐次地將元素傳入callbackfn,最終結果會產生一個值,並回傳。
let ary = [1, 2, 3, 4, 5, 6];
console.log(ary.reduce(function (x, y) {
return x + y;
}, 0)); //21
它的運作方式如下:
callbackfn第一次執行時,若有initialValue,則accumulator會等於initialValue,currentValue會等於陣列的第一個元素值。若無initialValue,則accumulator會等於陣列的第一個元素值,currentValue會等於陣列的第二個元素值。
以上面的例子來說,第一次執行時,x=0,y=1,回傳值為0+1=1。
第二次執行callbackfn,accumulator會是上一次執行的回傳值,也就是1,currentValue是上次傳入做為引數的元素的下一個,也就是第二個元素,值為2。
依此類推,第三次x=3,y=3,直到最後一個元素為止,reduce( )會回傳最終運算值:21。
參考來源:
MDN Array
JavaScript大全
Speaking JavaScript|簡明完整的 JS 精要指南
新一代 JavaScript 程式設計精解